//
// Mixins for Zen Columns layout method.
//

$legacy-support-for-ie6: true !default;


//
// This mixin should be applied to a container so that the children elements
// become columns arranged with the Zen Columns layout method.
//
// The mixin has the following required parameters:
// - $selectors: A list of selectors for all the columns inside the container.
//   In this list, order the columns as you would like them to appear from
//   left-to-right (or right-to-left when the $leading-direction is "right".)
//   Note that the HTML for the columns can be in any order in the HTML source.
// - $widths: A list of widths. Each one corresponds to a column specified in
//   $selectors. e.g. The first width is for the first column. The second width
//   is for the second column. etc.
//
// The mixin has the following optional parameters:
// - $box-sizing: The type of CSS3 box model each column should use. Can be set
//   to content-box or border-box. Defaults to content-box, but border-box is
//   way cooler. IE 6 and 7 don't support border-box.
// - $leading-direction: The direction the columns should float. Can be set to
//   "left" or "right". An extremely advanced option allows you to specify a
//   a list of directions, one direction for each column.
// - $leading-gutters: A list of leading gutters; one per column. The leading
//   gutter specifies the distance between the current column and the column
//   floated just before it.
// - $padding: A list of padding measurements; one per column. In order to
//   specify a complex padding value like "0 4px 2px", you can use nested lists,
//   e.g. $padding: ((0 4px 2px), (3px 0), (10px 5px 5px 10px))
//   In order to use the same padding measurements for all columns, you can
//   simply list one measurement total instead of one per column,
//   e.g. $padding: ((5px 10px))
//
// In addition to standard columns, the mixin supports one horizontal navbar
// that will appear (with a fixed height) above all the other columns. The
// parameters for this optional navbar are:
// - $navbar-selector: The selector for the navbar. It should be a child element
//   of the container just as a normal column is.
// - $navbar-height: The fixed height of the navbar. Required if the
//   $navbar-selector is used.
// - $navbar-width: The width of the navbar. Defaults to 100% of the container
//   width.
// - $navbar-leading-gutter: An optional leading space between the navbar and
//   and the container's inner edge. If specified, the $navbar-width must also
//   be specified so that the width plus leading gutter plus padding isn't
//   greater than 100% of the container's width.
// - $navbar-padding: An optional padding for the navbar. If specified, the
//   $navbar-width must also be specified so that the width plus leading gutter
//   plus padding isn't greater than 100% of the container's width.
//
@mixin zen-columns (
  // Information about the columns.
  $box-sizing: content-box,
  $selectors: ('.sidebar1', '.content', '.sidebar2'),
  $widths: (),
  $leading-direction: (),
  $leading-gutters: (),
  $padding: (),

  // Information about the navbar.
  $navbar-selector: false,
  $navbar-height: 0,
  $navbar-width: 100%,
  $navbar-leading-gutter: 0,
  $navbar-padding: 0
) {

  // Allow some parameters to be simple strings instead of lists.
  @if type_of($widths) != list {
    $widths: ($widths);
  }
  @if type_of($leading-direction) != list {
    $leading-direction: ($leading-direction);
  }
  @if type_of($leading-gutters) != list {
    $leading-gutters: ($leading-gutters);
  }
  @if type_of($padding) != list {
    $padding: ($padding);
  }
  @if type_of($navbar-padding) != list {
    $navbar-padding: ($navbar-padding);
  }

  // Declare all our variables so they can be used in any child block scope.
  $col: 0;
  $float: left;
  @if length($leading-direction) > 0 {
    $float: nth($leading-direction, 1);
  }
  $gutter: 0;
  $left-fill: 0;
  $left-reset: 0;
  $right-fill: 0;
  $right-reset: 0;
  $margin: 0;
  $padding-values: 0;
  $padding-x: 0;
  $navbar-padding-x: 0;
  $navbar-padding-y: 0;
  $navbar-reset: 0;
  $navbar-true-height: 0;
  $container-children: $selectors;

  @if $navbar-selector {
    // Determine the padding height and width of the navbar.
    $navbar-padding-x: 2 * nth($navbar-padding, 1);
    $navbar-padding-y: 2 * nth($navbar-padding, 1);
    @if length($navbar-padding) == 4 {
      $navbar-padding-x: nth($navbar-padding, 2) + nth($navbar-padding, 4);
    }
    @else if length($navbar-padding) >= 2 {
      $navbar-padding-x: 2 * nth($navbar-padding, 2);
    }
    @if length($navbar-padding) >= 3 {
      $navbar-padding-y: nth($navbar-padding, 1) + nth($navbar-padding, 3);
    }
    // We only keep track of the padding for content-box layouts.
    @if $box-sizing == border-box {
      $navbar-padding-x: 0;
    }
    // Determine the distance of the navbar's right edge from the container's left edge.
    $navbar-reset: -$navbar-leading-gutter - $navbar-width - $navbar-padding-x;
    // The columns need to know the true height of the navbar box.
    $navbar-true-height: $navbar-height + $navbar-padding-y;
    // Add the navbar to the list of the selectors of the container's children.
    $container-children: append($container-children, $navbar-selector);
  }

  // #{} interpolation doesn't work when converting lists into selectors, so
  // convert the list into an unquoted string before using it.
  $string: false;
  @each $child in $container-children {
    @if $string == false {
      $string: unquote($child);
    }
    @else {
      $string: unquote($string + ', ' + $child);
    }
  }
  $container-children: $string;

  // Iterate over each column.
  @each $column in $selectors {
    // Number the columns.
    $col: $col + 1;
    // Find the width, floating direction and gutter of the current column.
    $width: nth($widths, $col);
    @if $col <= length($leading-direction) {
      $float: nth($leading-direction, $col);
    }
    @if $col <= length($leading-gutters) {
      $gutter: nth($leading-gutters, $col);
    }
    // Calculate the left/right padding as it affects the true width of the column.
    @if $col <= length($padding) {
      $padding-values: nth($padding, $col);
      @if type_of($padding-values) != list {
        $padding-values: ($padding-values);
      }
      $padding-x: 2 * nth($padding-values, 1);
      @if length($padding-values) == 4 {
        $padding-x: nth($padding-values, 2) + nth($padding-values, 4);
      }
      @else if length($padding-values) > 1 {
        $padding-x: 2 * nth($padding-values, 2);
      }
    }
    // We only keep track of the padding for content-box layouts.
    @if $box-sizing == border-box {
      $padding-x: 0;
    }
    // If the column is floating from the left, determine the distance from the
    // container's left edge to the column's left edge ($left-fill) and to the
    // column's right edge ($left-reset).
    @if $float == left {
      $left-fill: $left-fill + $gutter;
      $left-reset: -$left-fill - $padding-x - $width;
      $margin: $navbar-true-height $left-reset 0 $left-fill;
      // The next column needs to know how much the previous columns have filled.
      $left-fill: $left-fill + $width + $padding-x;
    }
    // If the column is floating from the right, determine the distance from the
    // container's right edge to the column's right edge ($right-fill) and to
    // the column's left edge ($right-reset).
    @else {
      $right-fill: $right-fill + $gutter;
      $right-reset: -$right-fill - $padding-x - $width;
      $margin: $navbar-true-height $right-fill 0 $right-reset;
      // The next column needs to know how much the previous columns have filled.
      $right-fill: $right-fill + $width + $padding-x;
    }

    // Apply rules to the columns.
    #{$column} {
      float: $float;
      width: $width;
      margin: $margin;
      padding: $padding-values;
    }
  }

  // Apply rules to the container.
  position: relative;

  // Apply rules to the navbar.
  @if $navbar-selector {
    #{$navbar-selector} {
      float: $float;
      height: $navbar-height;
      margin: 0 $navbar-reset 0 $navbar-leading-gutter;
      width: $navbar-width;
      padding: $navbar-padding;
    }
  }

  // Apply rules to navbar and columns.
  #{$container-children} {
    // Specify the border-box properties.
    @if $box-sizing == border-box {
      -moz-box-sizing: border-box;
      -webkit-box-sizing: border-box;
      -ms-box-sizing: border-box;
      box-sizing: border-box;
    }
    // Prevent borders since they'll break the layout with content-box.
    @if $box-sizing == content-box {
      border: 0 !important;
    }
    // Prevent overflowing content from breaking the layout.
    overflow: visible;
    word-wrap: break-word; // A very nice CSS3 property.

    @if $legacy-support-for-ie6 and $box-sizing == content-box {
      .ie6 & {
        display: inline; // display inline or double your floated margin! [1]
        overflow: hidden; // in IE6, overflow auto is broken [2] and so is overflow visible [3]
        overflow-y: visible;
      }
    }
  }
}

// REFERENCES
//
// 1. http://www.positioniseverything.net/explorer/doubled-margin.html
// 2. http://browservulsel.blogspot.com/2005/04/ie-overflow-auto-scrollbar-overlap.html
// 3. http://www.howtocreate.co.uk/wrongWithIE/?chapter=overflow%3Avisible%3B
